#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

#define ETH_IFACE_NAME "eth0"

int gv_socket_init_and_bind (int *sockfd, struct sockaddr_in *sockaddr, int broadcast)
{
    struct ifreq ifr;
    uint32_t bcast_addr;
    
    *sockfd = socket (AF_INET, SOCK_DGRAM, IPPROTO_IP);
    if (*sockfd < 0) {
        PRINT_ERROR ("Failed to create socket\n");
        return -1;
    }
    
    memset (sockaddr, 0, sizeof(*sockaddr));
    sockaddr->sin_family = AF_INET;
    sockaddr->sin_addr.s_addr = htonl (INADDR_ANY);
    sockaddr->sin_port = htons (GVCP_PORT);
    
    if (broadcast == 1) {
        setsockopt (*sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast_opt));
    
        strcpy (ifr.ifr_name, ETH_IFACE_NAME);
    
        if (ioctl (*sockfd, SIOCGIFBRDADDR, &ifr) < 0) {
            PRINT_ERROR ("Unable to get broadcast address");
            close (*sockfd);
            return -2;
        }
    
        bcast_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
        sockaddr->sin_addr.s_addr = bcast_addr;
    }
    
    if (bind (*sockfd, (struct sockaddr *)sockaddr, sizeof(*sockaddr)) < 0) {
        PRINT_ERROR ("Failed to bind socket\n");
        close (sockfd);
        return -3;
    }
    
    return 0;
}

